package gamecomponents;

/**
 * A timer to count the time.
 * 
 * @author Team Deer
 * 
 */
public class Timer implements Cloneable, Runnable {

	private int milliSeconds;
	private final int timePerTick;
	private boolean isRunning;
	private final Thread thread;

	// Constructors

	/**
	 * Constructs a new Timer
	 * 
	 * @param timePerTick
	 *            how many millisecond one tick represents
	 */
	public Timer(final int timePerTick) {
		this.milliSeconds = 0;
		this.timePerTick = timePerTick;
		this.isRunning = false;
		this.thread = new Thread(this);
	}

	/**
	 * Constructs a new Timer
	 * 
	 * @param milliSeconds
	 *            start value in milliseconds
	 * @param timePerTicks
	 *            how many millisecond one tick represents
	 * @param isRunning
	 *            true if the timer should run from start
	 */
	public Timer(final int milliSeconds, final int timePerTicks,
			final boolean isRunning) {
		this.milliSeconds = milliSeconds;
		this.timePerTick = timePerTicks;
		this.isRunning = isRunning;
		this.thread = new Thread(this);
	}

	@Override
	public void run() {
		try {
			while (true) {
				Thread.sleep(this.timePerTick);
				if (this.isRunning) {
					this.milliSeconds += this.timePerTick;
				}
			}
		} catch (final InterruptedException ie) {
			System.out.println("Timer interrupted");
		}
	}

	/**
	 * Starts the timer
	 */
	public void startTimer() {
		try {
			this.thread.start();
			this.isRunning = true;
		} catch (final IllegalThreadStateException ite) {
			// You cant start a thread 2 times
		}
	}

	// Methods

	/**
	 * Stops the timer
	 */
	public void stopTimer() {
		if (this.thread.isAlive()) {
			this.thread.interrupt();
		}
		this.isRunning = false;
	}

	/**
	 * Pause the timer
	 */
	public void pauseTimer() {
		this.isRunning = false;
	}

	/**
	 * Resume the timer
	 */
	public void resumeTimer() {
		this.isRunning = true;
	}

	/**
	 * @return true if the timer is running
	 */
	public boolean isRunning() {
		return this.isRunning;
	}

	/**
	 * Resets the timer.
	 */
	public void resetTimer() {
		this.milliSeconds = 0;
	}

	/**
	 * 
	 * @return milliseconds per tick
	 */
	public int getTimePerTick() {
		return this.timePerTick;
	}

	/**
	 * 
	 * @return total elapsed milliseconds
	 */
	public int getTotalElapsedMilliSeconds() {
		return this.milliSeconds;
	}

	/**
	 * 
	 * @return the hour part of the time
	 */
	public int getHours() {
		return this.milliSeconds / 3600000;
	}

	/**
	 * 
	 * @return the minute part of the time
	 */
	public int getMinutes() {
		return this.milliSeconds / 60000 % 60;
	}

	/**
	 * 
	 * @return the second part of the time
	 */
	public int getSeconds() {
		return (this.milliSeconds / 1000) % 60;
	}

	/**
	 * 
	 * @return The millisecond part of the time
	 */
	public int getMilliSeconds() {
		return this.milliSeconds % 1000;
	}

	/**
	 * Clones the current timer.
	 */
	@Override
	public Timer clone() {
		return new Timer(this.milliSeconds, this.timePerTick, this.isRunning);
	}
}
